﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.MemoryMappedFiles;

namespace InCom.Core.TerminalSend.MappedFile
{
    /// <summary>
    /// 工场创建类,这个类在多进程创建中不适用
    /// </summary>
    public class Factory
    {

        private static readonly Factory instance = new Factory();

        /// <summary>
        /// 用于外部访问的实例
        /// </summary>
        public static Factory Instance
        {
            get { return instance; }
        }


        protected Factory()
        {
            access = MemoryMappedFileOperater.Instance.AccessorView;
        }

        /// <summary>
        /// 偏移量
        /// </summary>
        private long offset = 0;
        /// <summary>
        /// 偏移量
        /// </summary>
        public long Offset
        {
            get { return offset; }
         protected   set { offset = value; }
        }
        /// <summary>
        /// 文件视图
        /// </summary>
        MemoryMappedViewAccessor access;
        /// <summary>
        /// 文件视图对像
        /// </summary>
        public MemoryMappedViewAccessor Access
        {
            get { return access; }
            set { access = value; }
        }

        public MString CreateMString(int maxStringLen = 512)
        {
            MString strin = new MString(offset, access, maxStringLen);
            CheckOut(strin.FileMaxLength);
            //设置依稀量
            System.Threading.Interlocked.Add(ref offset, strin.FileMaxLength);
            return strin;
        }
        /// <summary>
        /// 创建一个int对像
        /// </summary>
        /// <returns></returns>
        public MInt CreateMInt()
        {
            MInt m = new MInt(offset, access);
            CheckOut(4);
            //设置依稀量
            System.Threading.Interlocked.Add(ref offset, 4);
            return m;
        }
        /// <summary>
        /// 创建一个Double对像
        /// </summary>
        /// <returns></returns>
        public MDouble CreateMDouble()
        {
            MDouble m = new MDouble(offset, access);
            CheckOut(8);
            //设置依稀量
            System.Threading.Interlocked.Add(ref offset, 8);
            return m;
        }

        /// <summary>
        /// 创建一个Float对像
        /// </summary>
        /// <returns></returns>
        public MFloat CreateMFloat()
        {
            MFloat m = new MFloat(offset, access);
            CheckOut(4);
            //设置依稀量
            System.Threading.Interlocked.Add(ref offset, 4);
            return m;
        }

        /// <summary>
        /// 创建一个DateTime对像
        /// </summary>
        /// <returns></returns>
        public MDateTime CreateMDateTime()
        {
            MDateTime m = new MDateTime(offset, access);
            CheckOut(8);
            //设置依稀量
            System.Threading.Interlocked.Add(ref offset, 8);
            return m;
        }
        /// <summary>
        /// 创建一个Long对像
        /// </summary>
        /// <returns></returns>
        public MLong CreateMLong()
        {
            MLong m = new MLong(offset, access);
            CheckOut(8);
            //设置依稀量
            System.Threading.Interlocked.Add(ref offset, 8);
            return m;
        }
        /// <summary>
        /// 创建一个bool对像
        /// </summary>
        /// <returns></returns>
        public MBool CreateMBool()
        {
            MBool m = new MBool(offset, access);
            CheckOut(1);
            //设置依稀量
            System.Threading.Interlocked.Add(ref offset, 1);
            return m;
        }
        /// <summary>
        /// 检查是不是,超过了最大使用空间
        /// </summary>
        /// <param name="len">使用空间的长度</param>
        protected void CheckOut(long len)
        {
            if (access.Capacity < offset + len)
            {
                throw new NotSupportedException("没有足够的空间完成创建对像工作,映射文件空间已经用完");
            }
        }
    }
}
